# coding=utf-8

from typing import List
import openpyxl
from openpyxl.styles import Alignment

from parse.parse_types import Module
from parse.sdb_parser import ECU

# 更新前务必确认一下原始文件是否有更新不属于APVP相关的模块,或者以排除的模块中名称是否有变化
excludes = ["SYS", "LOG", "radio", "audioPrimary", "audioSecond"]


class SignalConfig:

    def __init__(self, name, serviceId, ap_prot, vp_port, files) -> None:
        self.name = name
        self.serviceId = serviceId
        self.ap_port = ap_prot
        self.vp_port = vp_port
        self.files = files

def wirteSheetHeader(sheet):
    sheet.cell(1, 1, "OP_ID")
    sheet.cell(1, 2, "OP_NAME")
    sheet.cell(1, 3, "DIRECTION")
    sheet.cell(1, 4, "OP_TYPE")
    sheet.cell(1, 5, "CYCLIC_TIME(ms)")
    sheet.cell(1, 6, "DATA_STRUCT_NAME")

def create_rx_sheet(excle):
    for i in range(2):
        name = "RX"+str(i+1)
        sheet = excle.create_sheet(name)
        wirteSheetHeader(sheet)

        sheet.cell(2, 1, "2577")
        sheet.cell(2, 2, "getAllSignal")
        sheet.cell(2, 3, "AP->VP")
        sheet.cell(2, 4, "0x01 SETREQUEST_NORETURN")

        sheet.cell(3, 1, str(1001+i))
        sheet.cell(3, 2, name)
        sheet.cell(3, 2)
        sheet.cell(3, 3, "VP->AP")
        sheet.cell(3, 4, "0x05 NOTIFICATION")
        sheet.cell(3, 6, "Op{}_Notification".format(name))


def update_service_config_sheet(excle, ecus: List[ECU], modules: List[Module]):
    sheet = excle["ServiceConfig"]
    del_rows = []
    for row_index in range(3, sheet.max_row+1):
        value = sheet.cell(row_index, 2).value
        if value not in excludes:
            del_rows.append(row_index)

    for row in del_rows:
        sheet.delete_rows(row)
    index = del_rows[0]
    print("start index {}".format(str(index)))
    # 合并ecu和cbpa
    signalConfigs: List[SignalConfig] = []
    for ecu in sorted(ecus, key=lambda e: int(e.getServiceId()[1])):
        files = ""
        if ecu.hasWriteSignals() and ecu.hasReadSignals():
            files = "{name}_TX.h\n{name}_RX.h".format(name=ecu.name.upper())
        elif ecu.hasWriteSignals():
            files = "{name}_TX.h".format(name=ecu.name.upper())
        elif ecu.hasReadSignals():
            files = "{name}_RX.h".format(name=ecu.name.upper())
        signalConfigs.append(SignalConfig(
            ecu.name.upper(), ecu.getServiceId()[1], 50335, 50500, files))

    signalConfigs.append(SignalConfig("RX1", "97", 50335, 50500, "RX1.h"))
    signalConfigs.append(SignalConfig("RX2", "98", 50335, 50500, "RX2.h"))
    for module in sorted(modules, key=lambda m: int(m.service_id)):
        if module.name.lower() == "carconfig":
            continue
        signalConfigs.append(SignalConfig(module.name.upper(
        ), module.service_id, 50335, 50500, "{}.h".format(module.name)))

    for config in sorted(signalConfigs, key=lambda c: int(c.serviceId)):
        sheet.cell(index, 2, config.name)
        sheet.cell(index, 3, config.serviceId)
        sheet.cell(index, 4, config.ap_port)
        sheet.cell(index, 5, config.vp_port)
        sheet.cell(index, 6, config.files).alignment = Alignment(
            wrap_text=True)
        index += 1


def getAPVPModule(excle):
    sheet = excle["ServiceConfig"]
    modules = []
    for row_index in range(3, sheet.max_row+1):
        value = sheet.cell(row_index, 2).value
        if value not in excludes:
            modules.append(value)
    return modules


def gen_apvp_interface_excle(ecus: List[ECU], modules: List[Module]):
    excle = openpyxl.load_workbook(
        "./config/ipcp/apvp_excle/IPCP_Service_Operations_APVP.xlsx")
    # 读取现有的APVP模块
    module_sheets = getAPVPModule(excle)
    # 删除模块的sheet页
    for m in module_sheets:
        try:
            excle.remove(excle[m])
        except:
            pass

    # 创建新的内容
    for ecu in sorted(ecus, key=lambda e: int(e.getServiceId()[1])):
        sheet = excle.create_sheet(ecu.name.upper())
        wirteSheetHeader(sheet)
        index = 2
        for group in sorted(ecu.txSignals, key=lambda group: group.opcode):
            sheet.cell(index, 1, group.opcode)
            sheet.cell(index, 2, group.name.replace("_", ""))
            sheet.cell(index, 3, "AP->VP")
            sheet.cell(index, 4, "0x01 SETREQUEST_NORETURN")
            sheet.cell(index, 6, "Op{}_SetRequestNoReturn".format(group.name))
            index += 1
        if ecu.name.lower().startswith("carconfig") or ecu.name.lower().startswith("timeout"):
            sheet.cell(index, 1, "2577")
            sheet.cell(index, 2, "getAllSignal")
            sheet.cell(index, 3, "AP->VP")
            sheet.cell(index, 4, "0x01 SETREQUEST_NORETURN")
            index += 1

        if ecu.hasReadSignals():
            sheet.cell(index, 1, ecu.rxPackage.opcode)
            sheet.cell(index, 2, "{0}".format(ecu.name))
            sheet.cell(index, 3, "VP->AP")
            sheet.cell(index, 4, "0x05 NOTIFICATION")
            sheet.cell(index, 6, "Op{}_Notification".format(ecu.name))

    # 添加RX1和RX2 sheet
    create_rx_sheet(excle)

    for module in sorted(modules, key=lambda m: int(m.service_id)):
        if module.name.lower() == "carconfig":
            continue
        sheet = excle.create_sheet(module.name.upper())
        wirteSheetHeader(sheet)

        index = 2
        for cb in module.cb_apis:
            sheet.cell(index, 1, cb.op_id)
            sheet.cell(index, 2, cb.api.replace("_", "").lower())
            sheet.cell(index, 3, "AP->VP")
            sheet.cell(index, 4, "0x01 SETREQUEST_NORETURN")
            sheet.cell(index, 6, cb.get_send_struct_name())
            index += 1
        if len(module.pa_apis) > 0:
            sheet.cell(index, 1, "200")
            sheet.cell(index, 2, "{}Notification".format(module.name))
            sheet.cell(index, 3, "VP->AP")
            sheet.cell(index, 4, "0x05 NOTIFICATION")
            sheet.cell(index, 6, "Op{}_Notification".format(
                module.name))
    update_service_config_sheet(excle, ecus, modules)
    #临时关闭，减少冲突，由统一的人员定时上传保证进版apvp表与代码一致
    #excle.save("./config/ipcp/apvp_excle/IPCP_Service_Operations_APVP.xlsx")
